package com.suitsoft.ut.util;

import java.math.BigDecimal;

import org.apache.commons.lang.StringUtils;

/**
 * 金额转换处理类,a.小写转大写;(b.大写转小写)
 * <ul>
 * <li>处理能力：</li>
 * <li>a.整数部分：9999999999999999(16位长，仟万亿级)</li>
 * <li>b.小数部分：3位(可扩展，单位?)，多于3位舍去(不四舍五入)</li>
 * <li>可无限扩展,方法：IUNIT后依次递加合适的单位，并处理0出现在关键位置</li>
 * </ul>
 * 
 * @author JIM
 * @version 2.1
 */
public class MoneyToChinese {

	/** 大写数字 */
	private static final String[] NUMBERS = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };

	/** 整数部分的单位 */
	private static final String[] IUNIT = { "元", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", "万", "拾", "佰",
			"仟" };

	/** 小数部分的单位 */
	private static final String[] DUNIT = { "角", "分", "厘" };

	/** 整数部分长度限制，仟万亿级 */
	private static final int LIMIT = 16;

	private MoneyToChinese() {

	}

	/**
	 * 得到中文金额.
	 * 
	 * @return 中文金额
	 */
	public static String toChinese(String str) {
		// 去掉","
		String number = getFormatNum(str);
		//防止科学记数
		BigDecimal big = new BigDecimal(number);
		str = big.setScale(4, 2) +"";
		// 不是金额，直接返回
		if (!isMoney(number)) {
			return number;
		}
		// 整数部分数字
		String integerStr;
		// 小数部分数字
		String decimalStr;

		// 初始化：格式数字；分离整数部分和小数部分；确定长度
		if (number.indexOf(".") > 0) {
			integerStr = number.substring(0, number.indexOf("."));
			decimalStr = number.substring(number.indexOf(".") + 1);
		} else if (number.indexOf(".") == 0) {
			integerStr = "";
			decimalStr = number.substring(1);
		} else {
			integerStr = number;
			decimalStr = "";
		}

		// integerStr去掉首0，不必去掉decimalStr的尾0(超出部分舍去)
		if (!integerStr.equals("")) {
			integerStr = Long.toString(Long.parseLong(integerStr));
			if (integerStr.equals("0")) {
				integerStr = "";
			}
		}

		// overflow超出处理能力，直接返回
		if (integerStr.length() > LIMIT) {
			return number;
		}

		// 整数部分数字
		int[] integers = toArray(integerStr);
		// 设置万单位
		boolean isMust5 = isMust5(integerStr);
		// 小数部分数字
		int[] decimals = toArray(decimalStr);

		// 返回大写金额
		return getChineseInteger(integers, isMust5) + getChineseDecimal(decimals);
	}

	/**
	 * 整数部分和小数部分转换为数组，从高位至低位
	 */
	private static int[] toArray(String number) {
		int[] array = new int[number.length()];

		for (int i = 0; i < number.length(); i++) {
			array[i] = Integer.parseInt(number.substring(i, i + 1));
		}

		return array;
	}

	/**
	 * 得到中文金额的整数部分。
	 * 
	 * @return 整数部分
	 */
	private static String getChineseInteger(int[] integers, boolean isMust5) {
		StringBuffer chineseInteger = new StringBuffer("");
		String key = "";

		int length = integers.length;

		for (int ii = 0; ii < length; ii++) {
			// 1234(万)5678(亿)9012(万)3456(元)
			// 0出现在关键位置：元、万、亿、万亿、兆、万兆、亿兆、万亿兆
			// 处理顺序：不限，只跟具体位置有关，不必从高位到低位
			// 特殊情况：10(拾元、壹拾元、壹拾万元、拾万元)
			if (integers[ii] == 0) {
				// 万(亿)(必填)
				if ((length - ii) == 13) {
					key = IUNIT[4];
					// 亿(必填)
				} else if ((length - ii) == 9) {
					key = IUNIT[8];
					// 万(不必填)
				} else if ((length - ii) == 5 && isMust5) {
					key = IUNIT[4];
					// 元(必填)
				} else if ((length - ii) == 1) {
					key = IUNIT[0];
				}

				// 0遇非0时补零，不包含最后一位
				if ((length - ii) > 1 && integers[ii + 1] != 0) {
					key += NUMBERS[0];
					// 其余情况
				} else {
					key += "";
				}
			}

			chineseInteger.append(integers[ii] == 0 ? key : (NUMBERS[integers[ii]] + IUNIT[length - ii - 1]));

			key = "";
		}

		return chineseInteger.toString();
	}

	/**
	 * 得到中文金额的小数部分。
	 * 
	 * @return 小数部分
	 */
	private static String getChineseDecimal(int[] decimals) {
		StringBuffer chineseDecimal = new StringBuffer("");

		//如果小数部分都是0
		if (decimals == null || decimals.length == 0
				|| (decimals[0] == 0 && (decimals.length == 1 || decimals[1] == 0))) {
			chineseDecimal.append("整");
		} else if ((decimals[0] != 0 && (decimals.length > 1 && decimals[1] == 0))
				|| (decimals[0] != 0 && decimals.length == 1)) {
//			for (int ii = 0; ii < decimals.length - 1; ii++) {
//				// 舍去3位小数之后的
//				if (ii == 3) {
//					break;
//				}

				chineseDecimal.append(NUMBERS[decimals[0]] + DUNIT[0]).append("整");
//			}
		} else {
			for (int ii = 0; ii < decimals.length; ii++) {
				// 舍去3位小数之后的
				if (ii == 3) {
					break;
				}

				chineseDecimal.append(NUMBERS[decimals[ii]] + DUNIT[ii]);
			}
		}

		return chineseDecimal.toString();
	}

	/**
	 * 格式化数字：去掉","。
	 * 
	 * @param num  数字
	 * @return 格式化后的数字
	 */
	private static String getFormatNum(String number) {
		return StringUtils.replace(number, ",", "");
	}

	/**
	 * 判断第5位数字的单位"万"是否应加。
	 * 
	 * @return true是false否
	 */
	private static boolean isMust5(String integerStr) {
		int length = integerStr.length();

		if (length > 4) {
			String subInteger = "";

			if (length > 8) {
				// 取得从低位数，第5到第8位的字串
				subInteger = integerStr.substring(length - 8, length - 4);
			} else {
				subInteger = integerStr.substring(0, length - 4);
			}

			return Integer.parseInt(subInteger) > 0;
		} else {
			return false;
		}
	}

	/**
	 * 判断金额字符串是否合法 不合法：a.包含多于一个"."；b.包含"."、","和数字以外的字符；c.￥/$?。
	 * 
	 * @return true是false否
	 */
	private static boolean isMoney(String number) {
		try {
			Double.parseDouble(number);
		} catch (Exception ex) {
			return false;
		}

		return true;
	}

	public static void main(String[] args) {
		String num1 = "5206535.22";
		String monye1 = MoneyToChinese.toChinese(num1);
		System.out.println(num1 + "---------" + monye1);
		//		String num2 = "1002542.00";
		//		String monye2 = MoneyToChinese.toChinese(num2);
		//		System.out.println(num2 + "---------" + monye2);
		//		String num3 = "10452542.02";
		//		String monye3 = MoneyToChinese.toChinese(num3);
		//		System.out.println(num3 + "---------" + monye3);
		//		String num4 = "10452542.25";
		//		String monye4 = MoneyToChinese.toChinese(num4);
		//		System.out.println(num4 + "---------" + monye4);

		//		String num1 = "0.979";
		//		System.out.println(num1 + "-" + MoneyToChinese.toChinese(num1));
		//		String num2 = "09999999999999999";
		//		System.out.println(num2 + "-" + MoneyToChinese.toChinese(num2));
		//		String num3 = "10,001,000.09";
		//		System.out.println(num3 + "-" + MoneyToChinese.toChinese(num3));
		//		String num4 = "01.107000";
		//		System.out.println(num4 + "-" + MoneyToChinese.toChinese(num4));

		//		String num5 = "1.0778879";
		//		System.out.println(num5 + "-" + MoneyToChinese.toChinese(num5));
		//		String num6 = "1,002,002,020,000,201.897675434";
		//		System.out.println(num6 + "-" + MoneyToChinese.toChinese(num6));
		//		String num7 = "201000000";
		//		System.out.println(num7 + "-" + MoneyToChinese.toChinese(num7));
	}
}